package indi.zhifa.recipe.bailan.framework.mysql.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;

import java.time.LocalDateTime;

/**
 * Description: 
 * @Copyright: Copyright (c) 2020-2028 北京华咨电力科技发展有限公司 All rights reserved.
 * @author: 褚智勇(hataksumo@163.com)
 * @date:  2022/4/24 11:22
 */
@Slf4j
public abstract class BaseMetaObjectHandler implements MetaObjectHandler {

    protected static final Long SYS_ID = 0L;
    protected static final String SYS_NAME = "sys";
    protected static final String SYS_IP = "localhost";

    protected String createTimeStr = "createTime";
    protected String createByStr= "createBy";
    protected String createByNameStr = "createName";
    protected String createIpStr = "createIp";
    protected String versionStr = "version";

    protected String modifyTimeStr = "modifyTime";
    protected String modifyByStr= "modifyBy";
    protected String modifyByNameStr = "modifyName";
    protected String modifyIpStr = "modifyIp";


    protected boolean checkFieldNull(MetaObject pMetaObject, String pField){
        if(pMetaObject.hasSetter(modifyTimeStr)){
            Object orgModifyTime = pMetaObject.getValue(modifyTimeStr);
            if(null == orgModifyTime){
                return true;
            }
        }
        return false;
    }

    protected void insertVersion(MetaObject pMetaObject){
        if(checkFieldNull(pMetaObject,versionStr)){
            this.strictInsertFill(pMetaObject,versionStr,()-> 0, Integer.class);
        }
    }

    protected void insertCreateTime(MetaObject pMetaObject){
        if(checkFieldNull(pMetaObject,createTimeStr)){
            this.strictInsertFill(pMetaObject,createTimeStr,()-> LocalDateTime.now(),LocalDateTime.class);
        }
    }

    protected abstract void insertCreateBy(MetaObject pMetaObject);

    protected abstract void insertCreateByName(MetaObject pMetaObject);

    protected abstract void insertCreateByIp(MetaObject pMetaObject);

    abstract protected void otherInsertFill(MetaObject pMetaObject);

    abstract protected boolean hasTokenObject();

    @Override
    public void insertFill(MetaObject pMetaObject) {
        insertCreateTime(pMetaObject);
        insertVersion(pMetaObject);
        if(hasTokenObject()){
            try{
                if(checkFieldNull(pMetaObject,createByStr)){
                    insertCreateBy(pMetaObject);
                }
                if(checkFieldNull(pMetaObject,createByNameStr)){
                    insertCreateByName(pMetaObject);
                }
                if(checkFieldNull(pMetaObject,createIpStr)){
                    insertCreateByIp(pMetaObject);
                }

            }catch (Exception ex){
                log.error("insertFill 出现异常",ex);
            }
        }else{
            if(checkFieldNull(pMetaObject,createByStr)){
                this.strictInsertFill(pMetaObject,createByStr,()->SYS_ID,Long.class);
            }
            if(checkFieldNull(pMetaObject,createByNameStr)){
                this.strictInsertFill(pMetaObject,createByNameStr,()->SYS_NAME,String.class);
            }
            if(checkFieldNull(pMetaObject,createIpStr)){
                this.strictInsertFill(pMetaObject,createIpStr,()->SYS_IP,String.class);
            }
        }
        otherInsertFill(pMetaObject);
    }

    protected void updateModifyTime(MetaObject pMetaObject){
        if(checkFieldNull(pMetaObject,modifyTimeStr)){
            this.strictUpdateFill(pMetaObject,modifyTimeStr,()-> LocalDateTime.now(),LocalDateTime.class);
        }
    }

    protected abstract void updateModifyBy(MetaObject pMetaObject);

    protected abstract void updateModifyByName(MetaObject pMetaObject);

    protected abstract void updateModifyByIp(MetaObject pMetaObject);

    abstract protected void otherUpdateFill(MetaObject pMetaObject);


    @Override
    public void updateFill(MetaObject pMetaObject) {
        updateModifyTime(pMetaObject);
        if(hasTokenObject()){
            try{
                if(checkFieldNull(pMetaObject,modifyByStr)){
                    updateModifyBy(pMetaObject);
                }
                if(checkFieldNull(pMetaObject,modifyByNameStr)){
                    updateModifyByName(pMetaObject);
                }
                if(checkFieldNull(pMetaObject,modifyIpStr)){
                    updateModifyByIp(pMetaObject);
                }
            }catch (Exception ex){
                log.error("updateFill 出现异常",ex);
            }
        }else{
            if(checkFieldNull(pMetaObject,modifyByStr)){
                this.strictUpdateFill(pMetaObject,modifyByStr,()->SYS_ID,Long.class);
            }
            if(checkFieldNull(pMetaObject,modifyByNameStr)){
                this.strictUpdateFill(pMetaObject,modifyByNameStr,()->SYS_NAME,String.class);
            }
            if(checkFieldNull(pMetaObject,modifyIpStr)){
                this.strictUpdateFill(pMetaObject,modifyIpStr,()->SYS_IP,String.class);
            }
        }
        otherUpdateFill(pMetaObject);
    }
}
